package  
{
	import flash.display.Shape;
	import flash.display.GradientType;
	import flash.filters.GlowFilter;
	import flash.filters.GradientGlowFilter;
	import flash.geom.Matrix;
	import org.flixel.*;
	
	/**
	 * ...
	 * @author Lachlan McInnes
	 */
	
	public class LightBulb extends FlxSprite
	{
		public var increaseTimer:FlxTimer;
		//public var decreaseTimer:FlxTimer;
		
		private var _powered:Boolean;
		private var _glowAlpha:Number = 0;
		private var _currentCharge:Number;
		private var _losesCharge:Boolean;
		private var _gainsCharge:Boolean;
		private var _minimumCharge:int;
		private var _maximumCharge:int;
		private var _currentPowerLevel:int;
		private var _maximumPowerLevel:int;
		private var _chargeLossSpeed:Number;
		private var _chargeGainSpeed:Number;		
		
		private var _minimumGlow:int = 30;
		
		private const _barWidth:uint = 39;
		private const _barHeight:uint = 10;
		
		public var glow:FlxSprite;
		public var powerBarBackground:FlxSprite;
		public var powerBarLevel1:FlxSprite;
		public var powerBarLevel2:FlxSprite;
		public var powerBarLevel3:FlxSprite;
		private var _counter:Number = 0.0;
		private var _fadeOutTime:Number = 1.0;
		
		/**
		 * @param	startingPower	Sets the starting power of an object.
		 * @param	maximumCharge	Sets the maximum charge level.
		 * @param	minimumCharge	Sets the minimum charge level.
		 * @param	chargeLossSpeed	Sets the amount of charge lost per decrement.
		 * @param	chargeGainSpeed	Sets the amount of charge gained per increment.
		 */
		public function LightBulb(X:Number = 0, Y:Number = 0, powered:Boolean = false, 
									startingPower:Number = 0, maximumPowerLevel:int = 3,
									maximumCharge:int = 150, minimumCharge:int = 0,
									chargeLossSpeed:Number = 5, chargeGainSpeed:Number = 50,
									losesCharge:Boolean = true, gainsCharge:Boolean = true) 
		{
			super(X, Y);
			
			glow = new FlxSprite(x + width / 2 + 3, y + height / 2 + 3);
			glow.exists = false;
			FlxG.state.add(glow);
			
			powerBarBackground = new FlxSprite (X - _barWidth / 2 + 8, Y - _barHeight - 10)
			powerBarBackground.createGraphic(_barWidth, _barHeight, 0xff000000);
			powerBarBackground.visible = false;
			powerBarBackground.alpha = .3;
			FlxG.state.add(powerBarBackground);
			
			powerBarLevel1 = new FlxSprite (X - _barWidth / 2 + 8, Y - _barHeight - 10)
			powerBarLevel1.createGraphic(_barWidth / 3, _barHeight, 0xffffff66);
			powerBarLevel1.visible = false;
			powerBarLevel1.alpha = 0.4;
			FlxG.state.add(powerBarLevel1);
			
			powerBarLevel2 = new FlxSprite (X - _barWidth / 2 + 8, Y - _barHeight - 10)
			powerBarLevel2.createGraphic(_barWidth / 3 * 2, _barHeight, 0xffffff33);
			powerBarLevel2.visible = false;
			powerBarLevel2.alpha = 0.4;
			FlxG.state.add(powerBarLevel2);
			
			powerBarLevel3 = new FlxSprite (X - _barWidth / 2 + 8, Y - _barHeight - 10)
			powerBarLevel3.createGraphic(_barWidth, _barHeight, 0xffffff00);
			powerBarLevel3.visible = false;
			powerBarLevel3.alpha = 0.4;
			FlxG.state.add(powerBarLevel3);
			
			loadGraphic(ImageFiles.lightbulb, true, false, 15, 15);
			addAnimation("on", [0]);
			addAnimation("off", [1]);
			
			_powered = powered;
			
			_maximumPowerLevel = maximumPowerLevel;
			if (chargeGainSpeed != 0)
			{
				_currentPowerLevel = startingPower / chargeGainSpeed;
			}
			else
			{
				_currentPowerLevel = 0;
			}
			_currentCharge = startingPower;
			_losesCharge = losesCharge;
			_gainsCharge = gainsCharge;
			_maximumCharge = maximumCharge;
			_minimumCharge = minimumCharge;
			_chargeLossSpeed = chargeLossSpeed;
			_chargeGainSpeed = chargeGainSpeed;
			
			increaseTimer = new FlxTimer(1);
			//decreaseTimer = new FlxTimer(1);
			
			// We register two increase listeners, one for the initial hit, and one for sucessive pulses
			increaseTimer.add(IncreasePowerStart, FlxTimer.START);
			increaseTimer.add(IncreasePower, FlxTimer.COMPLETE);
			//decreaseTimer.add(DecreasePower, FlxTimer.COMPLETE);
		}
		
		public function get powered():Boolean
		{
			return _powered;
		}
		
		public function get chargeSpeed():Number
		{
			return _chargeGainSpeed;
		}
		
		public function get currentPowerLevel():int
		{
			return _currentPowerLevel;
		}
		
		public function get charge():Number
		{
			return _currentCharge;
		}
		
		public function set charge(value:Number):void
		{
			_currentCharge = value > 0 ? Math.min(value, _maximumCharge) : _minimumCharge;
		}
		
		public function isFullyPowered():Boolean
		{
			if (_currentCharge < _maximumCharge)
			{
				return false;
			}
			else
			{
				return true;
			}
		}
		
		public function checkPower():void 
		{
			if (_currentCharge == _minimumCharge)
			{
				_powered = false;
			}
			else
			{
				_powered = true;
			}
		}
		
		public function DrainAllPower():void
		{
			_powered = false;
			_currentCharge = 0;
			_currentPowerLevel = 0;
			increaseTimer.stop();
			//decreaseTimer.start();
		}
		
		override public function update():void
		{
			if (_powered)
			{
				_glowAlpha = Math.min(1, _glowAlpha += .02);
				play("on");
			}
			else
			{
				_currentPowerLevel = 0;
				play("off");
			}
			
			updatePowerBar();
			
			super.update();
		}
		
		private function updatePowerBar():void
		{
			if (_counter < _fadeOutTime)
			{
				if (currentPowerLevel == 3)
				{
					_counter += FlxG.elapsed;
					
					powerBarLevel3.alpha = 1 - (_counter / _fadeOutTime);
				}
				
				switch (_currentPowerLevel)
				{
					case 1:
					powerBarBackground.visible = true;
					powerBarLevel1.visible = true;
					break;
					case 2:
					powerBarLevel1.visible = false;
					powerBarLevel2.visible = true;
					break;
					case 3:
					powerBarLevel2.visible = false;
					powerBarBackground.visible = false;
					powerBarLevel3.visible = true;
					break;
				}
			}
		}
		
		public function IncreasePowerStart():void
		{
			if (_gainsCharge)
			{
				SetGlow(ImageFiles.lightGlow1);
				
				Math.max(--PlayState.currentDesurationLevel, 0);
				
				_currentCharge += _chargeGainSpeed;
				_currentPowerLevel++;
				FlxG.play(SoundFiles.lightLevel1Sound);
				
				if (_currentCharge > _maximumCharge)
				{
					_currentCharge = _maximumCharge;
				}
				
				if (_currentPowerLevel > _maximumPowerLevel)
				{
					_currentPowerLevel = _maximumPowerLevel;
				}
				
				checkPower();
				
				PowerGauge.currentVolts--;
			}
		}
		
		public function IncreasePower():void
		{
			if (_gainsCharge)
			{
				Math.max(--PlayState.currentDesurationLevel, 0);
				
				_currentCharge += _chargeGainSpeed;
				switch (_currentPowerLevel++)
				{
					case 1:
					glow.x += glow.width / 2;
					glow.y += glow.height / 2;					
					SetGlow(ImageFiles.lightGlow2);
					FlxG.play(SoundFiles.lightLevel2Sound);
					break;
					case 2:
					glow.x += glow.width / 2;
					glow.y += glow.height / 2;					
					SetGlow(ImageFiles.lightGlow3);
					FlxG.play(SoundFiles.lightLevel3Sound);
					FlxG.flash.start(0x11ffffff, .2);
					break;
				}
				
				if (_currentCharge > _maximumCharge)
				{
					_currentCharge = _maximumCharge;
				}
				
				if (_currentPowerLevel > _maximumPowerLevel)
				{
					_currentPowerLevel = _maximumPowerLevel;
				}
				
				checkPower();
				
				PowerGauge.currentVolts--;				
			}
		}
		
		public function DecreasePower():void
		{
			if (_losesCharge)
			{
				_currentCharge -= _chargeLossSpeed;
				
				if (_currentCharge < _minimumCharge)
				{
					_currentCharge = _minimumCharge;
				}
				
				checkPower();
			}
		}
		
		private function SetGlow(image:Class):void
		{
			glow.loadGraphic(image);
			glow.x -= glow.width / 2;
			glow.y -= glow.height / 2;
			glow.exists = true;
			glow.blend = "screen";			
		}
		
	}

}